import { socket } from '@kit.NetworkKit';
import { CRC16M } from '../CRC16M';
import { ExecutiveLevel } from '../ExecutiveLevel';
import { ConnectionState } from '../interfaceData/ConnectionState';
import SocketMessage from '../interfaceData/SocketMessage';
import { SocketConfig } from '../interfaceData/SocketConfig';
import { SocketResponse } from '../interfaceData/SocketResponse';
import { BusinessError } from '@kit.BasicServicesKit';

export class SocketHcManager {
  // 单例实例
  private static instance: SocketHcManager;

  private readonly TAG: string = 'SocketHcManager'

  // TCP客户端
  private tcpClient: socket.TCPSocket | null = null;

  // 连接状态
  private connectionState: ConnectionState = ConnectionState.DISCONNECTED;

  // 消息队列
  private messageQueue: SocketMessage[] = [];

  // 当前正在处理的消息
  private currentMessage: SocketMessage | null = null;

  // 重连尝试次数
  private reconnectAttempts: number = 0;

  // 配置
  private config: SocketConfig;

  // 消息ID计数器
  private messageIdCounter: number = 0;

  // 连接状态变化回调
  private connectionStateChangeCallback: ((state: ConnectionState) => void) | null = null;

  // 消息队列最大长度
  private readonly MAX_QUEUE_LENGTH = 100;

  // 私有构造函数(单例模式)
  private constructor() {

  }

  // 获取单例实例
  public static getInstance(): SocketHcManager {
    if (!SocketHcManager.instance) {
      SocketHcManager.instance = new SocketHcManager();
    }
    return SocketHcManager.instance;
  }

  // 设置连接状态变化回调
  public setConnectionStateChangeCallback(callback: (state: ConnectionState) => void): void {
    this.connectionStateChangeCallback = callback;
  }

  // 更新连接状态
  private updateConnectionState(state: ConnectionState): void {
    this.connectionState = state;
    if (this.connectionStateChangeCallback) {
      this.connectionStateChangeCallback(state);
    }
  }

  // 初始化Socket连接
  public connect(config: SocketConfig): void {
    this.config = {
      reconnectAttempts: 5,
      reconnectInterval: 3000,
      responseTimeout: 1500,
      ...config
    };
    if (this.connectionState !== ConnectionState.DISCONNECTED) {
      console.log(this.TAG, 'Socket已在连接或已连接');
      return;
    }

    this.createSocket();
    this.connectToServer();
  }

  // 创建Socket实例
  private createSocket(): void {
    try {
      this.tcpClient = socket.constructTCPSocketInstance();

      // 注册监听器
      this.registerListeners();

      this.updateConnectionState(ConnectionState.DISCONNECTED);
    } catch (error) {
      console.error(this.TAG, '创建Socket失败:', (error as BusinessError).message);
      this.handleError(error as BusinessError);
    }
  }

  // 注册Socket监听器
  private registerListeners(): void {
    if (!this.tcpClient) {
      return;
    }

    // 连接建立回调
    this.tcpClient.on('connect', () => {
      console.log(this.TAG, 'Socket连接已建立');
      this.updateConnectionState(ConnectionState.CONNECTED);
      this.reconnectAttempts = 0;

      // 连接建立后发送队列中的消息
      this.processNextMessage();
    });

    // 数据接收回调
    this.tcpClient.on('message', (value: socket.SocketMessageInfo) => {

      try {
        let uint8Array = new Uint8Array(value.message)
        let response = CRC16M.getBufHexStr(uint8Array)
        console.log(this.TAG, '收到服务器响应:', response);

        // 处理响应
        this.handleResponse(response);
      } catch (error) {
        console.error(this.TAG, '处理响应数据失败:', (error as BusinessError).message);
      }
    });

    // 连接关闭回调
    this.tcpClient.on('close', () => {
      console.log(this.TAG, 'Socket连接已关闭');
      this.handleClose();
    });

    // 错误回调
    this.tcpClient.on('error', (error: BusinessError) => {
      console.error(this.TAG, 'Socket错误:', error.message);
      this.handleError(error);
    });
  }

  // 连接到服务器
  private connectToServer(): void {
    if (!this.tcpClient) {
      return;
    }

    try {
      this.updateConnectionState(ConnectionState.CONNECTING);
      console.log(this.TAG, '正在连接到服务器...');

      let netAddress: socket.NetAddress = {
        address: this.config.address,
        port: this.config.port
      }
      let tcpConnectOptions: socket.TCPConnectOptions = {
        address: netAddress,
        timeout: 6000
      }
      this.tcpClient.connect(tcpConnectOptions).then(() => {
      }).catch((error: BusinessError) => {
        console.error(this.TAG, '连接失败:', (error as BusinessError).message);
        this.handleError(error as BusinessError);
        this.attemptReconnect();
      });
    } catch (error) {
      console.error(this.TAG, '连接失败:', (error as BusinessError).message);
      this.handleError(error as BusinessError);
      this.attemptReconnect();
    }
  }

  // 处理连接关闭
  private handleClose(): void {
    this.updateConnectionState(ConnectionState.DISCONNECTED);

    // 清理当前消息
    if (this.currentMessage) {
      this.clearMessageTimeout(this.currentMessage);
      this.currentMessage.callback({
        success: false,
        error: 'connection_closed',
        message: '连接已关闭'
      });
      this.currentMessage = null;
    }

    // 失败所有队列中的消息
    this.failAllMessages('connection_closed', '连接已关闭');

    // 尝试重连
    this.attemptReconnect();
  }

  // 尝试重新连接
  private attemptReconnect(): void {
    if (this.reconnectAttempts >= this.config.reconnectAttempts!) {
      console.error(this.TAG, '已达到最大重连尝试次数，停止重连');
      return;
    }

    this.reconnectAttempts++;
    console.log(this.TAG, `尝试第 ${this.reconnectAttempts} 次重连，等待 ${this.config.reconnectInterval}ms`);

    // 延迟后重连
    setTimeout(() => {
      this.createSocket();
      this.connectToServer();
    }, this.config.reconnectInterval);
  }

  // 发送消息
  public sendMessage(content: string, executiveLevel: ExecutiveLevel,
    callback: (response: SocketResponse) => void): number {
    const message: SocketMessage = {
      id: ++this.messageIdCounter,
      content,
      timestamp: new Date().getTime(),
      callback,
      executiveLevel
    };

    // 检查连接状态
    if (this.connectionState !== ConnectionState.CONNECTED) {
      // 如果未连接，立即回调连接错误
      setTimeout(() => {
        callback({
          success: false,
          error: 'not_connected',
          message: 'Socket未连接，无法发送消息'
        });
      }, 0);

      return message.id;
    }

    // 将消息加入队列
    // this.messageQueue.push(message);

    // 根据优先级插入队列
    switch (executiveLevel) {
      case ExecutiveLevel.HIGH:
        // 高优先级插入队列开头
        this.messageQueue.unshift(message);
        break;
      case ExecutiveLevel.MEDIUM:
        // 中优先级插入队列中间（在低优先级之前）
        const lowPriorityIndex = this.messageQueue.findIndex(m => m.executiveLevel === ExecutiveLevel.LOW);
        if (lowPriorityIndex === -1) {
          this.messageQueue.push(message);
        } else {
          this.messageQueue.splice(lowPriorityIndex, 0, message);
        }
        break;
      case ExecutiveLevel.LOW:
        // 低优先级插入队列末尾
        this.messageQueue.push(message);
        break;
    }
    console.log(this.TAG, `消息已加入队列，ID: ${message.id}, 当前队列长度: ${this.messageQueue.length}`);

    // 如果没有正在处理的消息，开始处理
    if (!this.currentMessage) {
      this.processNextMessage();
    }

    this.checkAndLimitQueueLength()

    return message.id;
  }

  // 检查并限制消息队列长度
  private checkAndLimitQueueLength(): void {
    if (this.messageQueue.length > this.MAX_QUEUE_LENGTH) {
      // 只保留HIGH优先级的消息
      const highPriorityMessages = this.messageQueue.filter(
        msg => msg.executiveLevel === ExecutiveLevel.HIGH
      );

      // 记录被删除的消息数量
      const deletedCount = this.messageQueue.length - highPriorityMessages.length;

      // 拒绝被删除的消息
      this.messageQueue.forEach(msg => {
        if (msg.executiveLevel !== ExecutiveLevel.HIGH) {
          console.log(this.TAG, "消息队列已满，低优先级消息被丢弃")
        }
      });

      // 更新队列
      this.messageQueue = highPriorityMessages;
      console.log(this.TAG, `消息队列已满，已丢弃${deletedCount}条低优先级消息`)
      // 通知状态变化
      // this.notifyStatusChange(`消息队列已满，已丢弃${deletedCount}条低优先级消息`);
    }
  }

  // 处理下一条消息
  private processNextMessage(): void {
    // 如果没有连接，不处理
    if (this.connectionState !== ConnectionState.CONNECTED) {
      return;
    }

    // 如果当前有消息正在处理，或队列为空，不处理
    if (this.currentMessage || this.messageQueue.length === 0) {
      return;
    }

    // 从队列中取出第一条消息
    this.currentMessage = this.messageQueue.shift() as SocketMessage;

    if (this.currentMessage && this.tcpClient) {
      console.log(this.TAG, `发送消息 ID: ${this.currentMessage.id}, 内容: ${this.currentMessage.content}`);

      try {
        // 发送消息
        let hex = CRC16M.getSendBuf(this.currentMessage.content)
        let hexData = CRC16M.uint8ArrayToArrayBuffer(hex)

        let tcpSendOption: socket.TCPSendOptions = {
          data: hexData
        }
        this.tcpClient.send(tcpSendOption);

        // 设置超时定时器
        this.setMessageTimeout(this.currentMessage);
      } catch (error) {
        console.error(this.TAG, '发送消息失败:', (error as BusinessError).message);

        // 回调错误
        this.currentMessage.callback({
          success: false,
          error: 'send_failed',
          message: (error as BusinessError).message
        });

        this.currentMessage = null;
        this.processNextMessage();
      }
    }
  }

  // 设置消息超时定时器
  private setMessageTimeout(message: SocketMessage): void {
    message.timeoutTimer = setTimeout(() => {
      console.log(this.TAG, `消息 ID: ${message.id} 响应超时`);

      // 只有当前消息是这条消息时才处理
      if (this.currentMessage && this.currentMessage.id === message.id) {
        this.currentMessage.callback({
          success: false,
          error: 'timeout',
          message: '响应超时'
        });

        this.currentMessage = null;
        this.processNextMessage();
      }
    }, this.config.responseTimeout!) as unknown as number;
  }

  // 清理消息超时定时器
  private clearMessageTimeout(message: SocketMessage): void {
    if (message.timeoutTimer) {
      clearTimeout(message.timeoutTimer);
      message.timeoutTimer = undefined;
    }
  }

  // 处理服务器响应
  private handleResponse(response: string): void {
    if (!this.currentMessage) {
      console.log(this.TAG, '收到响应但没有待处理的消息');
      return;
    }

    // 清理超时定时器
    this.clearMessageTimeout(this.currentMessage);

    // 执行回调
    try {
      this.currentMessage.callback({
        success: true,
        data: response
      });
    } catch (error) {
      console.error(this.TAG, '执行回调失败:', (error as BusinessError).message);
    }

    // 处理下一条消息
    this.currentMessage = null;
    this.processNextMessage();
  }

  // 处理错误
  private handleError(error: BusinessError): void {
    this.updateConnectionState(ConnectionState.DISCONNECTED);

    // 如果当前有消息正在处理，回调错误
    if (this.currentMessage) {
      this.clearMessageTimeout(this.currentMessage);
      this.currentMessage.callback({
        success: false,
        error: 'connection_error',
        message: error.message
      });
      this.currentMessage = null;
    }

    // 失败所有队列中的消息
    this.failAllMessages('connection_error', '连接错误: ' + error.message);
  }

  // 失败所有队列中的消息
  private failAllMessages(errorCode: string, errorMessage: string): void {
    // 复制队列以避免修改原数组时的迭代问题
    const failedMessages = [...this.messageQueue];
    this.messageQueue = [];

    // 回调所有失败的消息
    failedMessages.forEach(message => {
      message.callback({
        success: false,
        error: errorCode,
        message: errorMessage
      });
    });
  }

  // 关闭连接
  public close(): void {
    if (this.tcpClient) {
      try {
        this.tcpClient.close();
        this.tcpClient.off('connect');
        this.tcpClient.off('message');
        this.tcpClient.off('close');
        this.tcpClient.off('error');
      } catch (error) {
        console.error(this.TAG, '关闭连接失败:', (error as BusinessError).message);
      } finally {
        this.tcpClient = null;
        this.updateConnectionState(ConnectionState.DISCONNECTED);
      }
    }

    // 清理所有超时定时器
    this.messageQueue.forEach(message => {
      this.clearMessageTimeout(message);
    });

    // 清空消息队列
    this.messageQueue = [];

    if (this.currentMessage) {
      this.clearMessageTimeout(this.currentMessage);
      this.currentMessage = null;
    }

    // 重置重连计数
    this.reconnectAttempts = 0;
  }

  // 获取连接状态
  public getConnectionState(): ConnectionState {
    return this.connectionState;
  }

  // 获取队列长度
  public getQueueLength(): number {
    return this.messageQueue.length;
  }

  // 是否已连接
  public isConnected(): boolean {
    return this.connectionState === ConnectionState.CONNECTED;
  }
}